﻿using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;
using Sgr.BackGroundTasks;
using Sgr.Sms;
using Sgr.Sms.BackGroundTasks;
using Sgr.Utilities;

namespace Microsoft.Extensions.DependencyInjection
{
    /// <summary>
    ///
    /// </summary>
    public static class ServiceCollectionExtensions
    {
        private static readonly string[] ValidationMessages = new[]
        {
            "最大重试次数不能小于0",
            "重试间隔时间必须大于0秒",
            "发送频率限制必须大于0",
        };

        /// <summary>
        /// 添加短信发送功能
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configureOptions"></param>
        /// <returns></returns>
        public static IServiceCollection AddSms(this IServiceCollection services, Action<SmsOptions>? configureOptions = null)
        {
            // 检查是否已经注册
            if (services.Any(x => x.ServiceType == typeof(ISmsService)))
            {
                return services;
            }

            services.TryAddEnumerable(ServiceDescriptor.Singleton<ISmsProvider, DefaultSmsProvider>());

            services.TryAddTransient<ISmsService, DefaultSmsService>();

            services.AddOptions<SmsOptions>()
                .BindConfiguration("Sgr:Sms")
                .PostConfigure(options =>
                {
                    configureOptions?.Invoke(options);
                })
                .Validate(options =>
                {
                    try
                    {
                        ValidateSendingConfig(options);
                        return true;
                    }
                    catch (OptionsValidationException)
                    {
                        throw;
                    }
                    catch (Exception ex)
                    {
                        throw new OptionsValidationException(nameof(SmsOptions), typeof(SmsOptions),
                            new[] { $"配置验证失败: {ex.Message}" });
                    }
                });

            services.AddBackGroundTask<SmsSenderBackGroundTask, SmsSenderData>();
            services.Configure<BackGroundTaskOptions>(opts =>
            {
                opts.RegistBackGroundTask<SmsSenderBackGroundTask>();
            });

            return services;
        }

        private static void ValidateSendingConfig(SmsOptions options)
        {
            if (options.MaxRetryCount < 0)
                ThrowValidationException(0);

            if (options.RetryIntervalSeconds <= 0)
                ThrowValidationException(1);

            if (options.RateLimit <= 0)
                ThrowValidationException(2);
        }

        private static void ThrowValidationException(int messageIndex)
            => throw new OptionsValidationException(
                nameof(SmsOptions),
                typeof(SmsOptions),
                new[] { ValidationMessages[messageIndex] });
    }
}